﻿
using Microsoft.Extensions.DependencyInjection;
using Stee.CAP8.MessageBus.Interface.Interfaces;
using Stee.CAP8.MessageBus.Kafka.Publisher;
using Stee.CAP8.MessageBus.Kafka.Subscriber;
using Stee.CAP8.MessageBus.Sagas.Payment.Handlers;
using Stee.CAP8.MessageBus.Sagas.Payment.Sagas;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;

namespace Stee.CAP8.MessageBus.Sagas.Core.Extensions
{
    public static class MessageHandleExtension
    {

        public static IServiceCollection AddMessageHandle(this IServiceCollection services)
        {

            services.AddTransient<IPublisher, PublisherImpl>();
            services.AddTransient<ISubscriber, SubscriberImpl>();
            services.AddSingleton<SubSagaHandler>();

            var alltypes = Assembly.GetCallingAssembly().GetTypes();
            var typeHandle = typeof(ISubSaga);
            var implementSagaList = alltypes.Where(x => typeHandle.IsAssignableFrom(x)&&x!= typeHandle).ToList();


            implementSagaList.ForEach(type =>
            {
                services.AddSingleton(type);
                Console.WriteLine("注册成功" + type.FullName);

            });
            var provider = services.BuildServiceProvider();
            return services;
        }

        public static IServiceCollection UseMessageHandle(this IServiceCollection services) 
        {
            var provider = services.BuildServiceProvider();
            var handler = provider.GetService<SubSagaHandler>();
            handler.HandleEvent();
            return services;
        }



    }

    public static class TypeExtension
    {
        public static bool IsSubClassOfRawGeneric([NotNull] this Type type, [NotNull] Type generic)
        {
            if (type == null) throw new ArgumentNullException(nameof(type));
            if (generic == null) throw new ArgumentNullException(nameof(generic));

            while (type != null && type != typeof(object))
            {
                var isTheRawGenericType = IsTheRawGenericType(type);
                if (isTheRawGenericType) return true;
                type = type.BaseType;
            }

            return false;

            bool IsTheRawGenericType(Type test)
            => generic == (test.IsGenericType ? test.GetGenericTypeDefinition() : test);
        }
    }
}
